package com.chml.service.impl;

import com.chml.mapper.UserMapper;
import com.chml.pojo.User;
import com.chml.pojo.UserExample;
import com.chml.service.UserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Random;

/**
 * 实现与用户相关的数据库操作，包括用户的注册登录及修改密码
 */
@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {

    @Resource
    private UserMapper userMapper;
    private static Logger logger = LogManager.getRootLogger();
    char[] numbersAndLetters = ("0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ").toCharArray();//random seed

    /**
     * 判断用户的登录是否有效
     * @param account
     * @param password
     * @return
     * @throws Exception
     */
    public User Login(String account, String password) throws Exception{
        User user = userMapper.selectUserByAccount(account);
        if((user != null) && (user.getPassword().equals(password))){
            //update authorizeTime
            Date now = new Date();
            user.setLastAuthorizeTime(now);
            logger.debug("generate random access_token");
            Random random = new Random();
            char[] random_token = new char[12];
            for(int i = 0; i < 12; i++){
                random_token[i] = numbersAndLetters[random.nextInt(71)];
            }
            user.setAccessToken(new String(random_token));
            userMapper.updateByPrimaryKey(user);
        }
        return user;
    }

    /**
     * 修改用户密码
     * @param uid
     * @param old_password
     * @param new_password
     * @param access_token
     * @return
     * @throws Exception
     */
    public int ChangePassword(int uid, String old_password, String new_password, String access_token) throws Exception{
        User user = userMapper.selectByPrimaryKey(uid);
        if(user != null){
            if(user.getAccessToken().equals(access_token)){
                if(user.getPassword().equals(old_password)){
                    user.setPassword(new_password);
                    userMapper.updateByPrimaryKey(user);
                    return 1;
                }else{
                    return 0;//old_password is incorrect
                }
            }else {
                return 2;//access_token is incorrect
            }
        }else{
            return -1;//user not exists
        }
    }

    /**
     * 判断当前登陆状态是否有效
     * @param uid
     * @param accessToken
     * @return
     */
    @Override
    public boolean isValidRequest(int uid, String accessToken) throws Exception{
        User user = userMapper.selectByPrimaryKey(uid);
        return (user != null) && (user.getAccessToken().equals(accessToken));
    }

    @Override
    public boolean isValidRequest(String accessToken) {
        User user = getUserByToken(accessToken);
        if (user==null)
            return false;
        if (System.currentTimeMillis()>user.getLastAuthorizeTime().getTime()+2*3600000)
            return false;
        return true;
    }

    /**
     *注册新用户
     * @param account
     * @param password
     * @param nickname
     * @return
     */
    @Override
    public int createUser(String account, String password, String nickname) throws Exception{
        if (userMapper.selectUserByAccount(account)!=null)
            return -1;
        User user = new User();
        user.setAccount(account);
        user.setPassword(password);
        user.setUsername(nickname);
        user.setAccessToken("i34SyFs86hYy");
        Date current_time = new Date();
        user.setLastAuthorizeTime(current_time);
        return userMapper.insert(user);
    }

    @Override
    public User getUserByToken(String token) {
        if (token==null)
            return null;
        UserExample example = new UserExample();
        example.createCriteria().andAccessTokenEqualTo(token);
        try {
            return userMapper.selectByExample(example).get(0);
        } catch (IndexOutOfBoundsException e) {
            return null;
        }
    }
}
